/*! layDate 日期与时间控件 | MIT Licensed */
import '../css/modules/laydate/default/laydate.css'
import $ from 'jquery';
import layui from "./layui";
import lay from "./lay";

var
	ready = {
		getPath: (window.lay && lay.getPath) ? lay.getPath : ''
		//载入 CSS 依赖
		,link: function(href, fn, cssname){
}
	},
	//识别预先可能定义的指定全局对象
	GLOBAL = {}

	//外部调用
	, laydate = {
		v: '5.3.1' //layDate 版本号
		, config: {} //全局配置项
		, index: 0
		, path: ''

		//设置全局项
		, set: function (options) {
			var that = this;
			that.config = lay.extend({}, that.config, options);
			return that;
		}

		//主体CSS等待事件
		, ready: function (fn) {
			if	(typeof fn ==='function')fn();
		}
	}

	//操作当前实例
	, thisModule = function () {
		var that = this
			, options = that.config
			, id = options.id;

		thisModule.that[id] = that; //记录当前实例对象

		return {
			//提示框
			hint: function (content) {
				that.hint.call(that, content);
			}
			, config: that.config
		};
	}

	//字符常量
	, MOD_NAME = 'laydate', ELEM = '.layui-laydate', THIS = 'layui-this', SHOW = 'layui-show', HIDE = 'layui-hide',
	DISABLED = 'laydate-disabled', LIMIT_YEAR = [100, 200000]

	, ELEM_STATIC = 'layui-laydate-static', ELEM_LIST = 'layui-laydate-list', ELEM_SELECTED = 'laydate-selected',
	ELEM_HINT = 'layui-laydate-hint', ELEM_PREV = 'laydate-day-prev', ELEM_NEXT = 'laydate-day-next',
	ELEM_FOOTER = 'layui-laydate-footer', ELEM_CONFIRM = '.laydate-btns-confirm', ELEM_TIME_TEXT = 'laydate-time-text',
	ELEM_TIME_BTN = 'laydate-btns-time', ELEM_PREVIEW = 'layui-laydate-preview'

	//组件构造器
	, Class = function (options) {
		var that = this;
		that.index = ++laydate.index;
		that.config = lay.extend({}, that.config, laydate.config, options);

		//初始化 id 参数
		options = that.config;
		options.id = ('id' in options) ? options.id : that.index;

		//初始化
		laydate.ready(function () {
			that.init();
		});
	}

	//日期格式字符
	, dateType = 'yyyy|y|MM|M|dd|d|HH|H|mm|m|ss|s';

//将日期格式字符转换为数组
thisModule.formatArr = function (format) {
	return (format || '').match(new RegExp(dateType + '|.', 'g')) || []
};

/*
	组件操作
*/

//是否闰年
Class.isLeapYear = function (year) {
	return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
};

//默认配置
Class.prototype.config = {
	type: 'date' //控件类型，支持：year/month/date/time/datetime
	, range: false //是否开启范围选择，即双控件
	, format: 'yyyy-MM-dd' //默认日期格式
	, value: null //默认日期，支持传入new Date()，或者符合format参数设定的日期格式字符
	, isInitValue: true //用于控制是否自动向元素填充初始值（需配合 value 参数使用）
	, min: '1900-1-1' //有效最小日期，年月日必须用“-”分割，时分秒必须用“:”分割。注意：它并不是遵循 format 设定的格式。
	, max: '2099-12-31' //有效最大日期，同上
	, trigger: 'click' //呼出控件的事件
	, show: false //是否直接显示，如果设置 true，则默认直接显示控件
	, showBottom: true //是否显示底部栏
	, isPreview: true //是否显示值预览
	, btns: ['clear', 'now', 'confirm'] //右下角显示的按钮，会按照数组顺序排列
	, lang: 'cn' //语言，只支持cn/en，即中文和英文
	, theme: 'default' //主题
	, position: null //控件定位方式定位, 默认absolute，支持：fixed/absolute/static
	, calendar: false //是否开启公历重要节日，仅支持中文版
	, mark: {} //日期备注，如重要事件或活动标记
	, zIndex: null //控件层叠顺序
	, done: null //控件选择完毕后的回调，点击清空/现在/确定也均会触发
	, change: null //日期时间改变后的回调
};

//多语言
Class.prototype.lang = function () {
	var that = this
		, options = that.config
		, text = {
		cn: {
			weeks: ['日', '一', '二', '三', '四', '五', '六']
			, time: ['时', '分', '秒']
			, timeTips: '选择时间'
			, startTime: '开始时间'
			, endTime: '结束时间'
			, dateTips: '返回日期'
			, month: ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二']
			, tools: {
				confirm: '确定'
				, clear: '清空'
				, now: '现在'
			}
			, timeout: '结束时间不能早于开始时间<br>请重新选择'
			, invalidDate: '不在有效日期或时间范围内'
			, formatError: ['日期格式不合法<br>必须遵循下述格式：<br>', '<br>已为你重置']
			, preview: '当前选中的结果'
		}
		, en: {
			weeks: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']
			, time: ['Hours', 'Minutes', 'Seconds']
			, timeTips: 'Select Time'
			, startTime: 'Start Time'
			, endTime: 'End Time'
			, dateTips: 'Select Date'
			, month: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
			, tools: {
				confirm: 'Confirm'
				, clear: 'Clear'
				, now: 'Now'
			}
			, timeout: 'End time cannot be less than start Time<br>Please re-select'
			, invalidDate: 'Invalid date'
			, formatError: ['The date format error<br>Must be followed：<br>', '<br>It has been reset']
			, preview: 'The selected result'
		}
	};
	return text[options.lang] || text['cn'];
};

//初始准备
Class.prototype.init = function () {
	var that = this
		, options = that.config
		, isStatic = options.position === 'static'
		, format = {
		year: 'yyyy'
		, month: 'yyyy-MM'
		, date: 'yyyy-MM-dd'
		, time: 'HH:mm:ss'
		, datetime: 'yyyy-MM-dd HH:mm:ss'
	};

	options.elem = lay(options.elem);
	options.eventElem = lay(options.eventElem);

	if (!options.elem[0]) return;

	//日期范围分隔符
	that.rangeStr = options.range ? (typeof options.range === 'string' ? options.range : '-') : '';

	//若 range 参数为数组，则表示为开始日期和结束日期的 input 对象
	if (layui._typeof(options.range) === 'array') {
		that.rangeElem = [
			lay(options.range[0]),
			lay(options.range[1])
		];
	}

	//若 type 设置非法，则初始化为 date 类型
	if (!format[options.type]) {
		window.console && console.error && console.error('laydate type error:\'' + options.type + '\' is not supported')
		options.type = 'date';
	}

	//根据不同 type，初始化默认 format
	if (options.format === format.date) {
		options.format = format[options.type] || format.date;
	}

	//将日期格式转化成数组
	that.format = thisModule.formatArr(options.format);

	//生成正则表达式
	that.EXP_IF = '';
	that.EXP_SPLIT = '';
	lay.each(that.format, function (i, item) {
		var EXP = new RegExp(dateType).test(item)
			? '\\d{' + function () {
			if (new RegExp(dateType).test(that.format[i === 0 ? i + 1 : i - 1] || '')) {
				if (/^yyyy|y$/.test(item)) return 4;
				return item.length;
			}
			if (/^yyyy$/.test(item)) return '1,4';
			if (/^y$/.test(item)) return '1,308';
			return '1,2';
		}() + '}'
			: '\\' + item;
		that.EXP_IF = that.EXP_IF + EXP;
		that.EXP_SPLIT = that.EXP_SPLIT + '(' + EXP + ')';
	});
	//验证日期格式正则
	that.EXP_IF_ONE = new RegExp('^' + that.EXP_IF + '$'); //验证单个日期格式
	that.EXP_IF = new RegExp('^' + (
		options.range ?
			that.EXP_IF + '\\s\\' + that.rangeStr + '\\s' + that.EXP_IF
			: that.EXP_IF
	) + '$');
	that.EXP_SPLIT = new RegExp('^' + that.EXP_SPLIT + '$', '');

	//如果不是input|textarea元素，则默认采用click事件
	if (!that.isInput(options.elem[0])) {
		if (options.trigger === 'focus') {
			options.trigger = 'click';
		}
	}

	//设置唯一KEY
	if (!options.elem.attr('lay-key')) {
		options.elem.attr('lay-key', that.index);
		options.eventElem.attr('lay-key', that.index);
	}

	//记录重要日期
	options.mark = lay.extend({}, (options.calendar && options.lang === 'cn') ? {
		'0-1-1': '元旦'
		, '0-2-14': '情人'
		, '0-3-8': '妇女'
		, '0-3-12': '植树'
		, '0-4-1': '愚人'
		, '0-5-1': '劳动'
		, '0-5-4': '青年'
		, '0-6-1': '儿童'
		, '0-9-10': '教师'
		, '0-9-18': '国耻'
		, '0-10-1': '国庆'
		, '0-12-25': '圣诞'
	} : {}, options.mark);

	//获取限制内日期
	lay.each(['min', 'max'], function (i, item) {
		var ymd = [], hms = [];
		if (typeof options[item] === 'number') { //如果为数字
			var day = options[item]
				, time = new Date().getTime()
				, STAMP = 86400000 //代表一天的毫秒数
				, thisDate = new Date(
				day ? (
					day < STAMP ? time + day * STAMP : day //如果数字小于一天的毫秒数，则数字为天数，否则为毫秒数
				) : time
			);
			ymd = [thisDate.getFullYear(), thisDate.getMonth() + 1, thisDate.getDate()];
			day < STAMP || (hms = [thisDate.getHours(), thisDate.getMinutes(), thisDate.getSeconds()]);
		} else {
			ymd = (options[item].match(/\d+-\d+-\d+/) || [''])[0].split('-');
			hms = (options[item].match(/\d+:\d+:\d+/) || [''])[0].split(':');
		}
		options[item] = {
			year: ymd[0] | 0 || new Date().getFullYear()
			, month: ymd[1] ? (ymd[1] | 0) - 1 : new Date().getMonth()
			, date: ymd[2] | 0 || new Date().getDate()
			, hours: hms[0] | 0
			, minutes: hms[1] | 0
			, seconds: hms[2] | 0
		};
	});

	that.elemID = 'layui-laydate' + options.elem.attr('lay-key');

	if (options.show || isStatic) that.render();
	isStatic || that.events();

	//默认赋值
	if (options.value && options.isInitValue) {
		if (layui._typeof(options.value) === 'date') {
			that.setValue(that.parse(0, that.systemDate(options.value)));
		} else {
			that.setValue(options.value);
		}
	}
};

//控件主体渲染
Class.prototype.render = function () {
	var that = this
		, options = that.config
		, lang = that.lang()
		, isStatic = options.position === 'static'

		//主面板
		, elem = that.elem = lay.elem('div', {
			id: that.elemID
			, 'class': [
				'layui-laydate'
				, options.range ? ' layui-laydate-range' : ''
				, isStatic ? (' ' + ELEM_STATIC) : ''
				, options.theme && options.theme !== 'default' && !/^#/.test(options.theme) ? (' laydate-theme-' + options.theme) : ''
			].join('')
		})

		//主区域
		, elemMain = that.elemMain = []
		, elemHeader = that.elemHeader = []
		, elemCont = that.elemCont = []
		, elemTable = that.table = []

		//底部区域
		, divFooter = that.footer = lay.elem('div', {
			'class': ELEM_FOOTER
		});

	if (options.zIndex) elem.style.zIndex = options.zIndex;

	//单双日历区域
	lay.each(new Array(2), function (i) {
		if (!options.range && i > 0) {
			return true;
		}

		//头部区域
		var divHeader = lay.elem('div', {
				'class': 'layui-laydate-header'
			})

			//左右切换
			, headerChild = [function () { //上一年
				var elem = lay.elem('i', {
					'class': 'layui-icon laydate-icon laydate-prev-y'
				});
				elem.innerHTML = '&#xe65a;';
				return elem;
			}(), function () { //上一月
				var elem = lay.elem('i', {
					'class': 'layui-icon laydate-icon laydate-prev-m'
				});
				elem.innerHTML = '&#xe603;';
				return elem;
			}(), function () { //年月选择
				var elem = lay.elem('div', {
					'class': 'laydate-set-ym'
				}), spanY = lay.elem('span'), spanM = lay.elem('span');
				elem.appendChild(spanY);
				elem.appendChild(spanM);
				return elem;
			}(), function () { //下一月
				var elem = lay.elem('i', {
					'class': 'layui-icon laydate-icon laydate-next-m'
				});
				elem.innerHTML = '&#xe602;';
				return elem;
			}(), function () { //下一年
				var elem = lay.elem('i', {
					'class': 'layui-icon laydate-icon laydate-next-y'
				});
				elem.innerHTML = '&#xe65b;';
				return elem;
			}()]

			//日历内容区域
			, divContent = lay.elem('div', {
				'class': 'layui-laydate-content'
			})
			, table = lay.elem('table')
			, thead = lay.elem('thead'), theadTr = lay.elem('tr');

		//生成年月选择
		lay.each(headerChild, function (i, item) {
			divHeader.appendChild(item);
		});

		//生成表格
		thead.appendChild(theadTr);
		lay.each(new Array(6), function (i) { //表体
			var tr = table.insertRow(0);
			lay.each(new Array(7), function (j) {
				if (i === 0) {
					var th = lay.elem('th');
					th.innerHTML = lang.weeks[j];
					theadTr.appendChild(th);
				}
				tr.insertCell(j);
			});
		});
		table.insertBefore(thead, table.children[0]); //表头
		divContent.appendChild(table);

		elemMain[i] = lay.elem('div', {
			'class': 'layui-laydate-main laydate-main-list-' + i
		});

		elemMain[i].appendChild(divHeader);
		elemMain[i].appendChild(divContent);

		elemHeader.push(headerChild);
		elemCont.push(divContent);
		elemTable.push(table);
	});

	//生成底部栏
	lay(divFooter).html(function () {
		var html = [], btns = [];
		if (options.type === 'datetime') {
			html.push('<span lay-type="datetime" class="' + ELEM_TIME_BTN + '">' + lang.timeTips + '</span>');
		}
		if (!(!options.range && options.type === 'datetime')) {
			html.push('<span class="' + ELEM_PREVIEW + '" title="' + lang.preview + '"></span>')
		}

		lay.each(options.btns, function (i, item) {
			var title = lang.tools[item] || 'btn';
			if (options.range && item === 'now') return;
			if (isStatic && item === 'clear') title = options.lang === 'cn' ? '重置' : 'Reset';
			btns.push('<span lay-type="' + item + '" class="laydate-btns-' + item + '">' + title + '</span>');
		});
		html.push('<div class="laydate-footer-btns">' + btns.join('') + '</div>');
		return html.join('');
	}());

	//插入到主区域
	lay.each(elemMain, function (i, main) {
		elem.appendChild(main);
	});
	options.showBottom && elem.appendChild(divFooter);

	//生成自定义主题
	if (/^#/.test(options.theme)) {
		var style = lay.elem('style')
			, styleText = [
			'#{{id}} .layui-laydate-header{background-color:{{theme}};}'
			, '#{{id}} .layui-this{background-color:{{theme}} !important;}'
		].join('').replace(/{{id}}/g, that.elemID).replace(/{{theme}}/g, options.theme);

		if ('styleSheet' in style) {
			style.setAttribute('type', 'text/css');
			style.styleSheet.cssText = styleText;
		} else {
			style.innerHTML = styleText;
		}

		lay(elem).addClass('laydate-theme-molv');
		elem.appendChild(style);
	}

	//记录当前执行的实例索引
	laydate.thisId = options.id;

	//移除上一个控件
	that.remove(Class.thisElemDate);

	//如果是静态定位，则插入到指定的容器中，否则，插入到body
	isStatic ? options.elem.append(elem) : (
		document.body.appendChild(elem)
			, that.position() //定位
	);

	that.checkDate().calendar(null, 0, 'init'); //初始校验
	that.changeEvent(); //日期切换

	Class.thisElemDate = that.elemID;

	typeof options.ready === 'function' && options.ready(lay.extend({}, options.dateTime, {
		month: options.dateTime.month + 1
	}));

	that.preview();
};

//控件移除
Class.prototype.remove = function (prev) {
	var that = this
		, options = that.config
		, elem = lay('#' + (prev || that.elemID));
	if (!elem[0]) return that;

	if (!elem.hasClass(ELEM_STATIC)) {
		that.checkDate(function () {
			elem.remove();
			//delete options.dateTime;
			//delete that.endDate;
		});
	}
	return that;
};

//定位算法
Class.prototype.position = function () {
	var that = this
		, options = that.config;
	lay.position(that.bindElem || options.elem[0], that.elem, {
		position: options.position
	});
	return that;
};

//提示
Class.prototype.hint = function (content) {
	var that = this
		, options = that.config
		, div = lay.elem('div', {
		'class': ELEM_HINT
	});

	if (!that.elem) return;

	div.innerHTML = content || '';
	lay(that.elem).find('.' + ELEM_HINT).remove();
	that.elem.appendChild(div);

	clearTimeout(that.hinTimer);
	that.hinTimer = setTimeout(function () {
		lay(that.elem).find('.' + ELEM_HINT).remove();
	}, 3000);
};

//获取递增/减后的年月
Class.prototype.getAsYM = function (Y, M, type) {
	type ? M-- : M++;
	if (M < 0) {
		M = 11;
		Y--;
	}
	if (M > 11) {
		M = 0;
		Y++;
	}
	return [Y, M];
};

//系统日期
Class.prototype.systemDate = function (newDate) {
	var thisDate = newDate || new Date();
	return {
		year: thisDate.getFullYear() //年
		, month: thisDate.getMonth() //月
		, date: thisDate.getDate() //日
		, hours: newDate ? newDate.getHours() : 0 //时
		, minutes: newDate ? newDate.getMinutes() : 0 //分
		, seconds: newDate ? newDate.getSeconds() : 0 //秒
	}
};

//日期校验
Class.prototype.checkDate = function (fn) {
	var that = this
		, thisDate = new Date()
		, options = that.config
		, lang = that.lang()
		, dateTime = options.dateTime = options.dateTime || that.systemDate()
		, thisMaxDate, error

		, elem = that.bindElem || options.elem[0]
		, valType = that.isInput(elem) ? 'val' : 'html'
		, value = function () {
			//如果传入了开始和结束日期的 input 对象，则将其拼接为日期范围字符
			if (that.rangeElem) {
				var vals = [that.rangeElem[0].val(), that.rangeElem[1].val()];
				if (vals[0] && vals[1]) {
					return vals.join(' ' + that.rangeStr + ' ');
				}
			}
			return that.isInput(elem) ? elem.value : (options.position === 'static' ? '' : lay(elem).attr('lay-date'));
		}()

		//校验日期有效数字
		, checkValid = function (dateTime) {
			if (dateTime.year > LIMIT_YEAR[1]) dateTime.year = LIMIT_YEAR[1], error = true; //不能超过20万年
			if (dateTime.month > 11) dateTime.month = 11, error = true;
			if (dateTime.hours > 23) dateTime.hours = 0, error = true;
			if (dateTime.minutes > 59) dateTime.minutes = 0, dateTime.hours++, error = true;
			if (dateTime.seconds > 59) dateTime.seconds = 0, dateTime.minutes++, error = true;

			//计算当前月的最后一天
			thisMaxDate = laydate.getEndDate(dateTime.month + 1, dateTime.year);
			if (dateTime.date > thisMaxDate) dateTime.date = thisMaxDate, error = true;
		}

		//获得初始化日期值
		, initDate = function (dateTime, value, index) {
			var startEnd = ['startTime', 'endTime'];
			value = (value.match(that.EXP_SPLIT) || []).slice(1);
			index = index || 0;

			if (options.range) {
				that[startEnd[index]] = that[startEnd[index]] || {};
			}
			lay.each(that.format, function (i, item) {
				var thisv = parseFloat(value[i]);
				if (value[i].length < item.length) error = true;
				if (/yyyy|y/.test(item)) { //年
					if (thisv < LIMIT_YEAR[0]) thisv = LIMIT_YEAR[0], error = true; //年不能低于100年
					dateTime.year = thisv;
				} else if (/MM|M/.test(item)) { //月
					if (thisv < 1) thisv = 1, error = true;
					dateTime.month = thisv - 1;
				} else if (/dd|d/.test(item)) { //日
					if (thisv < 1) thisv = 1, error = true;
					dateTime.date = thisv;
				} else if (/HH|H/.test(item)) { //时
					if (thisv < 1) thisv = 0, error = true;
					dateTime.hours = thisv;
					options.range && (that[startEnd[index]].hours = thisv);
				} else if (/mm|m/.test(item)) { //分
					if (thisv < 1) thisv = 0, error = true;
					dateTime.minutes = thisv;
					options.range && (that[startEnd[index]].minutes = thisv);
				} else if (/ss|s/.test(item)) { //秒
					if (thisv < 1) thisv = 0, error = true;
					dateTime.seconds = thisv;
					options.range && (that[startEnd[index]].seconds = thisv);
				}
			});
			checkValid(dateTime);
		};

	if (fn === 'limit') return checkValid(dateTime), that;

	value = value || options.value;
	if (typeof value === 'string') {
		value = value.replace(/\s+/g, ' ').replace(/^\s|\s$/g, '');
	}

	//如果开启范围，则计算结束日期
	var getEndDate = function () {
		if (options.range) {
			that.endDate = that.endDate || lay.extend({}, options.dateTime, function () {
				var obj = {}
					, dateTime = options.dateTime
					, EYM = that.getAsYM(dateTime.year, dateTime.month);

				//初始右侧面板的年月
				if (options.type === 'year') {
					obj.year = dateTime.year + 1;
				} else if (options.type !== 'time') {
					obj.year = EYM[0];
					obj.month = EYM[1];
				}

				//初始右侧面板的时间
				if (options.type === 'datetime' || options.type === 'time') {
					obj.hours = 23;
					obj.minutes = obj.seconds = 59;
				}

				return obj;
			}());
		}
	};
	getEndDate();

	if (typeof value === 'string' && value) {
		if (that.EXP_IF.test(value)) { //校验日期格式
			if (options.range) {
				value = value.split(' ' + that.rangeStr + ' ');
				lay.each([options.dateTime, that.endDate], function (i, item) {
					initDate(item, value[i], i);
				});
			} else {
				initDate(dateTime, value);
			}
		} else {
			//格式不合法
			that.hint(lang.formatError[0] + (
				options.range ? (options.format + ' ' + that.rangeStr + ' ' + options.format) : options.format
			) + lang.formatError[1]);
			error = true;
		}
	} else if (value && layui._typeof(value) === 'date') { //如果值为日期对象时
		options.dateTime = that.systemDate(value);
	} else {
		//重置开始日期
		options.dateTime = that.systemDate();
		delete that.startTime;

		//重置结束日期
		delete that.endDate; //删除原有的结束日期
		getEndDate(); //并重新获得新的结束日期
		delete that.endTime;
	}

	//从日期范围表单中获取初始值
	(function () {
		if (that.rangeElem) {
			var vals = [that.rangeElem[0].val(), that.rangeElem[1].val()]
				, arrDate = [options.dateTime, that.endDate];
			lay.each(vals, function (_i, _v) {
				if (that.EXP_IF_ONE.test(_v)) { //校验日期格式
					initDate(arrDate[_i], _v, _i);
				}
			});
		}
	})();

	//校验日期有效数字
	checkValid(dateTime);
	if (options.range) checkValid(that.endDate);

	//如果初始值格式错误，则纠正初始值
	if (error && value) {
		that.setValue(
			options.range ? (that.endDate ? that.parse() : '') : that.parse()
		);
	}

	//如果当前日期不在设定的最大小日期区间，则自动纠正在可选区域
	var getDateTime = function (obj) {
		return that.newDate(obj).getTime();
	};

	//校验主面板是否在可选日期区间
	if (getDateTime(dateTime) > getDateTime(options.max) || getDateTime(dateTime) < getDateTime(options.min)) {
		dateTime = options.dateTime = lay.extend({}, options.min);
	}

	//校验右侧面板是否在可选日期区间
	if (options.range) {
		if (getDateTime(that.endDate) < getDateTime(options.min) || getDateTime(that.endDate) > getDateTime(options.max)) {
			that.endDate = lay.extend({}, options.max);
		}
	}

	fn && fn();
	return that;
};

//公历重要日期与自定义备注
Class.prototype.mark = function (td, YMD) {
	var that = this
		, mark, options = that.config;
	lay.each(options.mark, function (key, title) {
		var keys = key.split('-');
		if ((keys[0] == YMD[0] || keys[0] == 0) //每年的每月
			&& (keys[1] == YMD[1] || keys[1] == 0) //每月的每日
			&& keys[2] == YMD[2]) { //特定日
			mark = title || YMD[2];
		}
	});
	mark && td.html('<span class="laydate-day-mark">' + mark + '</span>');

	return that;
};

//无效日期范围的标记
Class.prototype.limit = function (elem, date, index, time) {
	var that = this
		, options = that.config, timestrap = {}
		, dateTime = options[index > 41 ? 'endDate' : 'dateTime']
		, isOut, thisDateTime = lay.extend({}, dateTime, date || {});

	lay.each({
		now: thisDateTime
		, min: options.min
		, max: options.max
	}, function (key, item) {
		timestrap[key] = that.newDate(lay.extend({
			year: item.year
			, month: item.month
			, date: item.date
		}, function () {
			var hms = {};
			lay.each(time, function (i, keys) {
				hms[keys] = item[keys];
			});
			return hms;
		}())).getTime();  //time：是否比较时分秒
	});

	isOut = timestrap.now < timestrap.min || timestrap.now > timestrap.max;
	elem && elem[isOut ? 'addClass' : 'removeClass'](DISABLED);
	return isOut;
};

//当前日期对象
Class.prototype.thisDateTime = function (index) {
	var that = this
		, options = that.config;
	return index ? that.endDate : options.dateTime;
};

//日历表
Class.prototype.calendar = function (value, index, type) {
	var that = this
		, options = that.config
		, index = index ? 1 : 0
		, dateTime = value || that.thisDateTime(index)
		, thisDate = new Date(), startWeek, prevMaxDate, thisMaxDate
		, lang = that.lang()

		, isAlone = options.type !== 'date' && options.type !== 'datetime'
		, tds = lay(that.table[index]).find('td')
		, elemYM = lay(that.elemHeader[index][2]).find('span');

	if (dateTime.year < LIMIT_YEAR[0]) dateTime.year = LIMIT_YEAR[0], that.hint(lang.invalidDate);
	if (dateTime.year > LIMIT_YEAR[1]) dateTime.year = LIMIT_YEAR[1], that.hint(lang.invalidDate);

	//记录初始值
	if (!that.firstDate) {
		that.firstDate = lay.extend({}, dateTime);
	}

	//计算当前月第一天的星期
	thisDate.setFullYear(dateTime.year, dateTime.month, 1);
	startWeek = thisDate.getDay();

	prevMaxDate = laydate.getEndDate(dateTime.month || 12, dateTime.year); //计算上个月的最后一天
	thisMaxDate = laydate.getEndDate(dateTime.month + 1, dateTime.year); //计算当前月的最后一天

	//赋值日
	lay.each(tds, function (index_, item) {
		var YMD = [dateTime.year, dateTime.month], st = 0;
		item = lay(item);
		item.removeAttr('class');
		if (index_ < startWeek) {
			st = prevMaxDate - startWeek + index_;
			item.addClass('laydate-day-prev');
			YMD = that.getAsYM(dateTime.year, dateTime.month, 'sub');
		} else if (index_ >= startWeek && index_ < thisMaxDate + startWeek) {
			st = index_ - startWeek;
			st + 1 === dateTime.date && item.addClass(THIS);
		} else {
			st = index_ - thisMaxDate - startWeek;
			item.addClass('laydate-day-next');
			YMD = that.getAsYM(dateTime.year, dateTime.month);
		}
		YMD[1]++;
		YMD[2] = st + 1;
		item.attr('lay-ymd', YMD.join('-')).html(YMD[2]);
		that.mark(item, YMD).limit(item, {
			year: YMD[0]
			, month: YMD[1] - 1
			, date: YMD[2]
		}, index_);
	});

	//同步头部年月
	lay(elemYM[0]).attr('lay-ym', dateTime.year + '-' + (dateTime.month + 1));
	lay(elemYM[1]).attr('lay-ym', dateTime.year + '-' + (dateTime.month + 1));

	if (options.lang === 'cn') {
		lay(elemYM[0]).attr('lay-type', 'year').html(dateTime.year + ' 年')
		lay(elemYM[1]).attr('lay-type', 'month').html((dateTime.month + 1) + ' 月');
	} else {
		lay(elemYM[0]).attr('lay-type', 'month').html(lang.month[dateTime.month]);
		lay(elemYM[1]).attr('lay-type', 'year').html(dateTime.year);
	}

	//初始默认选择器
	if (isAlone) { //年、月等独立选择器
		if (options.range) {
			if (value) {
				that.listYM = [
					[options.dateTime.year, options.dateTime.month + 1]
					, [that.endDate.year, that.endDate.month + 1]
				];
				that.list(options.type, 0).list(options.type, 1);

				//同步按钮可点状态
				options.type === 'time' ? that.setBtnStatus('时间'
					, lay.extend({}, that.systemDate(), that.startTime)
					, lay.extend({}, that.systemDate(), that.endTime)
				) : that.setBtnStatus(true);
			}
		} else {
			that.listYM = [[dateTime.year, dateTime.month + 1]];
			that.list(options.type, 0);
		}
	}

	//初始赋值双日历
	if (options.range && type === 'init' && !value) {
		//执行渲染第二个日历
		that.calendar(that.endDate, 1);
	}

	//通过检测当前有效日期，来设定确定按钮是否可点
	if (!options.range) that.limit(lay(that.footer).find(ELEM_CONFIRM), null, 0, ['hours', 'minutes', 'seconds']);

	//同步按钮可点状态
	that.setBtnStatus();

	return that;
};

//生成年月时分秒列表
Class.prototype.list = function (type, index) {
	var that = this
		, options = that.config
		, dateTime = options.dateTime
		, lang = that.lang()
		, isAlone = options.range && options.type !== 'date' && options.type !== 'datetime' //独立范围选择器

		, ul = lay.elem('ul', {
		'class': ELEM_LIST + ' ' + ({
			year: 'laydate-year-list'
			, month: 'laydate-month-list'
			, time: 'laydate-time-list'
		})[type]
	})
		, elemHeader = that.elemHeader[index]
		, elemYM = lay(elemHeader[2]).find('span')
		, elemCont = that.elemCont[index || 0]
		, haveList = lay(elemCont).find('.' + ELEM_LIST)[0]
		, isCN = options.lang === 'cn'
		, text = isCN ? '年' : ''

		, listYM = that.listYM[index] || {}
		, hms = ['hours', 'minutes', 'seconds']
		, startEnd = ['startTime', 'endTime'][index];

	if (listYM[0] < 1) listYM[0] = 1;

	//生成年列表
	if (type === 'year') {
		var yearNum, startY = yearNum = listYM[0] - 7;
		if (startY < 1) startY = yearNum = 1;
		lay.each(new Array(15), function (i) {
			var li = lay.elem('li', {
				'lay-ym': yearNum
			}), ymd = {year: yearNum};
			yearNum == listYM[0] && lay(li).addClass(THIS);
			li.innerHTML = yearNum + text;
			ul.appendChild(li);
			if (yearNum < that.firstDate.year) {
				ymd.month = options.min.month;
				ymd.date = options.min.date;
			} else if (yearNum >= that.firstDate.year) {
				ymd.month = options.max.month;
				ymd.date = options.max.date;
			}
			that.limit(lay(li), ymd, index);
			yearNum++;
		});
		lay(elemYM[isCN ? 0 : 1]).attr('lay-ym', (yearNum - 8) + '-' + listYM[1])
			.html((startY + text) + ' - ' + (yearNum - 1 + text));
	}

	//生成月列表
	else if (type === 'month') {
		lay.each(new Array(12), function (i) {
			var li = lay.elem('li', {
				'lay-ym': i
			}), ymd = {year: listYM[0], month: i};
			i + 1 == listYM[1] && lay(li).addClass(THIS);
			li.innerHTML = lang.month[i] + (isCN ? '月' : '');
			ul.appendChild(li);
			if (listYM[0] < that.firstDate.year) {
				ymd.date = options.min.date;
			} else if (listYM[0] >= that.firstDate.year) {
				ymd.date = options.max.date;
			}
			that.limit(lay(li), ymd, index);
		});
		lay(elemYM[isCN ? 0 : 1]).attr('lay-ym', listYM[0] + '-' + listYM[1])
			.html(listYM[0] + text);
	}

	//生成时间列表
	else if (type === 'time') {
		//检测时分秒状态是否在有效日期时间范围内
		var setTimeStatus = function () {
			lay(ul).find('ol').each(function (i, ol) {
				lay(ol).find('li').each(function (ii, li) {
					that.limit(lay(li), [{
						hours: ii
					}, {
						hours: that[startEnd].hours
						, minutes: ii
					}, {
						hours: that[startEnd].hours
						, minutes: that[startEnd].minutes
						, seconds: ii
					}][i], index, [['hours'], ['hours', 'minutes'], ['hours', 'minutes', 'seconds']][i]);
				});
			});
			if (!options.range) that.limit(lay(that.footer).find(ELEM_CONFIRM), that[startEnd], 0, ['hours', 'minutes', 'seconds']);
		};

		//初始化时间对象
		if (options.range) {
			if (!that[startEnd]) {
				that[startEnd] = startEnd === 'startTime' ? dateTime : that.endDate;
			}
		} else {
			that[startEnd] = dateTime;
		}

		//生成时分秒
		lay.each([24, 60, 60], function (i, item) {
			var li = lay.elem('li'), childUL = ['<p>' + lang.time[i] + '</p><ol>'];
			lay.each(new Array(item), function (ii) {
				childUL.push('<li' + (that[startEnd][hms[i]] === ii ? ' class="' + THIS + '"' : '') + '>' + lay.digit(ii, 2) + '</li>');
			});
			li.innerHTML = childUL.join('') + '</ol>';
			ul.appendChild(li);
		});
		setTimeStatus();
	}

	//插入容器
	if (haveList) elemCont.removeChild(haveList);
	elemCont.appendChild(ul);

	//年月面板 - 选择事件
	if (type === 'year' || type === 'month') {
		//显示切换箭头
		lay(that.elemMain[index]).addClass('laydate-ym-show');

		//选中
		lay(ul).find('li').on('click', function () {
			var ym = lay(this).attr('lay-ym') | 0;
			if (lay(this).hasClass(DISABLED)) return;

			if (index === 0) {
				dateTime[type] = ym;
				that.limit(lay(that.footer).find(ELEM_CONFIRM), null, 0);
			} else { //范围选择
				that.endDate[type] = ym;
			}

			//当为年选择器或者年月选择器
			var isYearOrMonth = options.type === 'year' || options.type === 'month';
			if (isYearOrMonth) {
				lay(ul).find('.' + THIS).removeClass(THIS);
				lay(this).addClass(THIS);

				//如果为年月选择器，点击了年列表，则切换到月选择器
				if (options.type === 'month' && type === 'year') {
					that.listYM[index][0] = ym;
					isAlone && ((index ? that.endDate : dateTime).year = ym);
					that.list('month', index);
				}
			} else {
				that.checkDate('limit').calendar(null, index);
				that.closeList();
			}

			that.setBtnStatus(); //同步按钮可点状态

			//若为月选择器，只有当选择月份时才自动关闭；
			//若为年选择器，选择年份即自动关闭
			//且在范围未开启时
			if (!options.range) {
				if ((options.type === 'month' && type === 'month') || (options.type === 'year' && type === 'year')) {
					that.setValue(that.parse()).remove().done();
				}
			}

			that.done(null, 'change');
			lay(that.footer).find('.' + ELEM_TIME_BTN).removeClass(DISABLED);
		});
	} else { //时间选择面板 - 选择事件
		var span = lay.elem('span', {
				'class': ELEM_TIME_TEXT
			})

			//滚动条定位
			, scroll = function () {
				lay(ul).find('ol').each(function (i) {
					var ol = this
						, li = lay(ol).find('li')
					ol.scrollTop = 30 * (that[startEnd][hms[i]] - 2);
					if (ol.scrollTop <= 0) {
						li.each(function (ii, item) {
							if (!lay(this).hasClass(DISABLED)) {
								ol.scrollTop = 30 * (ii - 2);
								return true;
							}
						});
					}
				});
			}
			, haveSpan = lay(elemHeader[2]).find('.' + ELEM_TIME_TEXT);

		scroll();
		span.innerHTML = options.range ? [lang.startTime, lang.endTime][index] : lang.timeTips;
		lay(that.elemMain[index]).addClass('laydate-time-show');

		if (haveSpan[0]) haveSpan.remove();
		elemHeader[2].appendChild(span);

		lay(ul).find('ol').each(function (i) {
			var ol = this;
			//选择时分秒
			lay(ol).find('li').on('click', function () {
				var value = this.innerHTML | 0;
				if (lay(this).hasClass(DISABLED)) return;

				if (options.range) {
					that[startEnd][hms[i]] = value;
				} else {
					dateTime[hms[i]] = value;
				}
				lay(ol).find('.' + THIS).removeClass(THIS);
				lay(this).addClass(THIS);

				setTimeStatus();
				scroll();
				(that.endDate || options.type === 'time') && that.done(null, 'change');

				//同步按钮可点状态
				that.setBtnStatus();
			});
		});
	}

	return that;
};

//记录列表切换后的年月
Class.prototype.listYM = [];

//关闭列表
Class.prototype.closeList = function () {
	var that = this
		, options = that.config;

	lay.each(that.elemCont, function (index, item) {
		lay(this).find('.' + ELEM_LIST).remove();
		lay(that.elemMain[index]).removeClass('laydate-ym-show laydate-time-show');
	});
	lay(that.elem).find('.' + ELEM_TIME_TEXT).remove();
};

//检测结束日期是否超出开始日期
Class.prototype.setBtnStatus = function (tips, start, end) {
	var that = this
		, options = that.config
		, lang = that.lang()
		, isOut, elemBtn = lay(that.footer).find(ELEM_CONFIRM);
	if (options.range && options.type !== 'time') {
		start = start || options.dateTime;
		end = end || that.endDate;
		isOut = that.newDate(start).getTime() > that.newDate(end).getTime();

		//如果不在有效日期内，直接禁用按钮，否则比较开始和结束日期
		(that.limit(null, start) || that.limit(null, end))
			? elemBtn.addClass(DISABLED)
			: elemBtn[isOut ? 'addClass' : 'removeClass'](DISABLED);

		//是否异常提示
		if (tips && isOut) that.hint(
			typeof tips === 'string' ? lang.timeout.replace(/日期/g, tips) : lang.timeout
		);
	}
};

//转义为规定格式的日期字符
Class.prototype.parse = function (state, date) {
	var that = this
		, options = that.config
		, dateTime = date || (state == 'end'
		? lay.extend({}, that.endDate, that.endTime)
		: (options.range ? lay.extend({}, options.dateTime, that.startTime) : options.dateTime))
		, format = laydate.parse(dateTime, that.format, 1);

	//返回日期范围字符
	if (options.range && state === undefined) {
		return format + ' ' + that.rangeStr + ' ' + that.parse('end');
	}

	return format;
};

//创建指定日期时间对象
Class.prototype.newDate = function (dateTime) {
	dateTime = dateTime || {};
	return new Date(
		dateTime.year || 1
		, dateTime.month || 0
		, dateTime.date || 1
		, dateTime.hours || 0
		, dateTime.minutes || 0
		, dateTime.seconds || 0
	);
};

//赋值
Class.prototype.setValue = function (value) {
	var that = this
		, options = that.config
		, elem = that.bindElem || options.elem[0];

	//静态展现则不作默认赋值
	if (options.position === 'static') return that;

	value = value || '';

	//绑定的元素是否为 input
	if (that.isInput(elem)) {
		lay(elem).val(value);
	} else {
		//如果 range 传入了开始和结束的 input 对象，则分别对其赋值
		if (that.rangeElem) {
			that.rangeElem[0].val(value ? that.parse('start') : '');
			that.rangeElem[1].val(value ? that.parse('end') : '');
		} else {
			if (lay(elem).find('*').length === 0) {
				lay(elem).html(value);
			}
			lay(elem).attr('lay-date', value);
		}
	}

	return that;
};

//预览
Class.prototype.preview = function () {
	var that = this
		, options = that.config;

	if (!options.isPreview) return;

	var elemPreview = lay(that.elem).find('.' + ELEM_PREVIEW)
		, value = options.range ? (that.endDate ? that.parse() : '') : that.parse();

	//显示预览
	elemPreview.html(value).css({
		'color': '#5FB878'
	});
	setTimeout(function () {
		elemPreview.css({
			'color': '#666'
		});
	}, 300);
};

//执行 done/change 回调
Class.prototype.done = function (param, type) {
	var that = this
		, options = that.config
		, start = lay.extend({}, lay.extend(options.dateTime, that.startTime))
		, end = lay.extend({}, lay.extend(that.endDate, that.endTime))

	lay.each([start, end], function (i, item) {
		if (!('month' in item)) return;
		lay.extend(item, {
			month: item.month + 1
		});
	});

	that.preview();

	param = param || [that.parse(), start, end];
	typeof options[type || 'done'] === 'function' && options[type || 'done'].apply(options, param);

	return that;
};

//选择日期
Class.prototype.choose = function (td, index) {
	var that = this
		, options = that.config
		, dateTime = that.thisDateTime(index)

		, tds = lay(that.elem).find('td')
		, YMD = td.attr('lay-ymd').split('-');

	YMD = {
		year: YMD[0] | 0
		, month: (YMD[1] | 0) - 1
		, date: YMD[2] | 0
	};

	if (td.hasClass(DISABLED)) return;

	lay.extend(dateTime, YMD); //同步 dateTime

	//范围选择
	if (options.range) {
		//补充时分秒
		lay.each(['startTime', 'endTime'], function (i, item) {
			that[item] = that[item] || {
				hours: 0
				, minutes: 0
				, seconds: 0
			};
		});
		that.calendar(null, index).done(null, 'change');
	} else if (options.position === 'static') { //直接嵌套的选中
		that.calendar().done().done(null, 'change'); //同时执行 done 和 change 回调
	} else if (options.type === 'date') {
		that.setValue(that.parse()).remove().done();
	} else if (options.type === 'datetime') {
		that.calendar().done(null, 'change');
	}
};

//底部按钮
Class.prototype.tool = function (btn, type) {
	var that = this
		, options = that.config
		, lang = that.lang()
		, dateTime = options.dateTime
		, isStatic = options.position === 'static'
		, active = {
		//选择时间
		datetime: function () {
			if (lay(btn).hasClass(DISABLED)) return;
			that.list('time', 0);
			options.range && that.list('time', 1);
			lay(btn).attr('lay-type', 'date').html(that.lang().dateTips);
		}

		//选择日期
		, date: function () {
			that.closeList();
			lay(btn).attr('lay-type', 'datetime').html(that.lang().timeTips);
		}

		//清空、重置
		, clear: function () {
			isStatic && (
				lay.extend(dateTime, that.firstDate)
					, that.calendar()
			)
			options.range && (
				delete options.dateTime
					, delete that.endDate
					, delete that.startTime
					, delete that.endTime
			);
			that.setValue('').remove();
			that.done(['', {}, {}]);
		}

		//现在
		, now: function () {
			var thisDate = new Date();
			lay.extend(dateTime, that.systemDate(), {
				hours: thisDate.getHours()
				, minutes: thisDate.getMinutes()
				, seconds: thisDate.getSeconds()
			});
			that.setValue(that.parse()).remove();
			isStatic && that.calendar();
			that.done();
		}

		//确定
		, confirm: function () {
			if (options.range) {
				if (lay(btn).hasClass(DISABLED)) return that.hint(
					options.type === 'time' ? lang.timeout.replace(/日期/g, '时间') : lang.timeout
				);
			} else {
				if (lay(btn).hasClass(DISABLED)) return that.hint(lang.invalidDate);
			}
			that.done();
			that.setValue(that.parse()).remove()
		}
	};
	active[type] && active[type]();
};

//统一切换处理
Class.prototype.change = function (index) {
	var that = this
		, options = that.config
		, dateTime = that.thisDateTime(index)
		, isAlone = options.range && (options.type === 'year' || options.type === 'month')

		, elemCont = that.elemCont[index || 0]
		, listYM = that.listYM[index]
		, addSubYeay = function (type) {
		var isYear = lay(elemCont).find('.laydate-year-list')[0]
			, isMonth = lay(elemCont).find('.laydate-month-list')[0];

		//切换年列表
		if (isYear) {
			listYM[0] = type ? listYM[0] - 15 : listYM[0] + 15;
			that.list('year', index);
		}

		if (isMonth) { //切换月面板中的年
			type ? listYM[0]-- : listYM[0]++;
			that.list('month', index);
		}

		if (isYear || isMonth) {
			lay.extend(dateTime, {
				year: listYM[0]
			});
			if (isAlone) dateTime.year = listYM[0];
			options.range || that.done(null, 'change');
			options.range || that.limit(lay(that.footer).find(ELEM_CONFIRM), {
				year: listYM[0]
			});
		}

		that.setBtnStatus();
		return isYear || isMonth;
	};

	return {
		prevYear: function () {
			if (addSubYeay('sub')) return;
			dateTime.year--;
			that.checkDate('limit').calendar(null, index);
			that.done(null, 'change');
		}
		, prevMonth: function () {
			var YM = that.getAsYM(dateTime.year, dateTime.month, 'sub');
			lay.extend(dateTime, {
				year: YM[0]
				, month: YM[1]
			});
			that.checkDate('limit').calendar(null, index);
			that.done(null, 'change');
		}
		, nextMonth: function () {
			var YM = that.getAsYM(dateTime.year, dateTime.month);
			lay.extend(dateTime, {
				year: YM[0]
				, month: YM[1]
			});
			that.checkDate('limit').calendar(null, index);
			that.done(null, 'change');
		}
		, nextYear: function () {
			if (addSubYeay()) return;
			dateTime.year++
			that.checkDate('limit').calendar(null, index);
			that.done(null, 'change');
		}
	};
};

//日期切换事件
Class.prototype.changeEvent = function () {
	var that = this
		, options = that.config;

	//日期选择事件
	lay(that.elem).on('click', function (e) {
		lay.stope(e);
	}).on('mousedown', function (e) {
		lay.stope(e);
	});

	//年月切换
	lay.each(that.elemHeader, function (i, header) {
		//上一年
		lay(header[0]).on('click', function (e) {
			that.change(i).prevYear();
		});

		//上一月
		lay(header[1]).on('click', function (e) {
			that.change(i).prevMonth();
		});

		//选择年月
		lay(header[2]).find('span').on('click', function (e) {
			var othis = lay(this)
				, layYM = othis.attr('lay-ym')
				, layType = othis.attr('lay-type');

			if (!layYM) return;

			layYM = layYM.split('-');

			that.listYM[i] = [layYM[0] | 0, layYM[1] | 0];
			that.list(layType, i);
			lay(that.footer).find('.' + ELEM_TIME_BTN).addClass(DISABLED);
		});

		//下一月
		lay(header[3]).on('click', function (e) {
			that.change(i).nextMonth();
		});

		//下一年
		lay(header[4]).on('click', function (e) {
			that.change(i).nextYear();
		});
	});

	//点击日期
	lay.each(that.table, function (i, table) {
		var tds = lay(table).find('td');
		tds.on('click', function () {
			that.choose(lay(this), i);
		});
	});

	//点击底部按钮
	lay(that.footer).find('span').on('click', function () {
		var type = lay(this).attr('lay-type');
		that.tool(this, type);
	});
};

//是否输入框
Class.prototype.isInput = function (elem) {
	return /input|textarea/.test(elem.tagName.toLocaleLowerCase());
};

//绑定的元素事件处理
Class.prototype.events = function () {
	var that = this
		, options = that.config

		//绑定呼出控件事件
		, showEvent = function (elem, bind) {
			elem.on(options.trigger, function () {
				bind && (that.bindElem = this);
				that.render();
			});
		};

	if (!options.elem[0] || options.elem[0].eventHandler) return;

	showEvent(options.elem, 'bind');
	showEvent(options.eventElem);

	options.elem[0].eventHandler = true;
};

//记录所有实例
thisModule.that = {}; //记录所有实例对象

//获取当前实例对象
thisModule.getThis = function (id) {
	var that = thisModule.that[id];
	if (!that && isLayui) layui.hint().error(id ? (MOD_NAME + ' instance with ID \'' + id + '\' not found') : 'ID argument required');
	return that;
};

//初始执行
ready.run = function () {
	//绑定关闭控件事件
	lay(document).on('mousedown', function (e) {
		if (!laydate.thisId) return;
		var that = thisModule.getThis(laydate.thisId);
		if (!that) return;

		var options = that.config;

		if (
			e.target === options.elem[0] ||
			e.target === options.eventElem[0] ||
			e.target === lay(options.closeStop)[0]
		) return;

		that.remove();

	}).on('keydown', function (e) {
		if (!laydate.thisId) return;
		var that = thisModule.getThis(laydate.thisId);
		if (!that) return;

		if (e.keyCode === 13) {
			if (lay('#' + that.elemID)[0] && that.elemID === Class.thisElemDate) {
				e.preventDefault();
				lay(that.footer).find(ELEM_CONFIRM)[0].click();
			}
		}
	});

	//自适应定位
	lay(window).on('resize', function () {
		if (!laydate.thisId) return;
		var that = thisModule.getThis(laydate.thisId);
		if (!that) return;

		if (!that.elem || !lay(ELEM)[0]) {
			return false;
		}

		that.position();
	});
};

//核心接口
laydate.render = function (options) {
	var inst = new Class(options);
	return thisModule.call(inst);
};

//将指定对象转化为日期值
laydate.parse = function (dateTime, format, one) {
	dateTime = dateTime || {};

	//如果 format 是字符型，则转换为数组格式
	if (typeof format === 'string') {
		format = thisModule.formatArr(format);
	}

	format = (format || []).concat();

	//转义为规定格式
	lay.each(format, function (i, item) {
		if (/yyyy|y/.test(item)) { //年
			format[i] = lay.digit(dateTime.year, item.length);
		} else if (/MM|M/.test(item)) { //月
			format[i] = lay.digit(dateTime.month + (one || 0), item.length);
		} else if (/dd|d/.test(item)) { //日
			format[i] = lay.digit(dateTime.date, item.length);
		} else if (/HH|H/.test(item)) { //时
			format[i] = lay.digit(dateTime.hours, item.length);
		} else if (/mm|m/.test(item)) { //分
			format[i] = lay.digit(dateTime.minutes, item.length);
		} else if (/ss|s/.test(item)) { //秒
			format[i] = lay.digit(dateTime.seconds, item.length);
		}
	});

	return format.join('');
};

//得到某月的最后一天
laydate.getEndDate = function (month, year) {
	var thisDate = new Date();
	//设置日期为下个月的第一天
	thisDate.setFullYear(
		year || thisDate.getFullYear()
		, month || (thisDate.getMonth() + 1)
		, 1);
	//减去一天，得到当前月最后一天
	return new Date(thisDate.getTime() - 1000 * 60 * 60 * 24).getDate();
};


laydate.ready();
ready.run();
export default laydate;



